package pers.cj.pdos.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import pers.cj.pdos.cache.CacheData;
import pers.cj.pdos.constant.GoodsAttrColor;
import pers.cj.pdos.constant.GoodsAttrName;
import pers.cj.pdos.constant.OrderType;
import pers.cj.pdos.cache.CacheRemove;
import pers.cj.pdos.entity.*;
import pers.cj.pdos.mapper.*;
import pers.cj.pdos.service.ICompanyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import pers.cj.pdos.utils.*;

import java.math.BigDecimal;
import java.util.*;

import static pers.cj.pdos.constant.GoodsAttrName.COLOR;

/**
 * <p>
 * 企业账号信息 服务实现类
 * </p>
 *
 * @author chenj
 * @since 2019-11-04
 */
@Service
public class CompanyServiceImpl extends ServiceImpl<CompanyMapper, Company> implements ICompanyService {
    @Autowired
    BusinessSetMapper businessSetMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    CompanyMapper companyMapper;
    @Autowired
    StoreMapper storeMapper;
    @Autowired
    HouseMapper houseMapper;
    @Autowired
    UserHouseMapper userHouseMapper;
    @Autowired
    RoleMapper roleMapper;
    @Autowired
    UserRoleMapper userRoleMapper;
    @Autowired
    PermissionMapper permissionMapper;
    @Autowired
    RolePermissionMapper rolePermissionMapper;
    @Autowired
    RetailSetMapper retailSetMapper;
    @Autowired
    OrderRuleMapper orderRuleMapper;
    @Autowired
    AttrNameMapper attrNameMapper;
    @Autowired
    AttrMapper attrMapper;

    @Override
    @CacheData(clazz = CompanyServiceImpl.class, param = "#id")
    public Company getById(String id) {
        return companyMapper.selectById(id);
    }

    @Override
    @CacheRemove(clazz = CompanyServiceImpl.class, methodName = "getById", param = "#company.id")
    public void update(Company company,String snIndustryId) {
        //设置业务设置的序列号开关
        BusinessSet businessSet = new BusinessSet();
        businessSet.setSerial(company.getIndustryId().equals(snIndustryId));
        businessSetMapper.update(businessSet,new UpdateWrapper<BusinessSet>().eq("company_id",company.getId()));

        //更新管理员姓名
        User admin = new User();
        admin.setName(company.getAdminName());
        userMapper.update(admin,new UpdateWrapper<User>().eq("company_id",company.getId()).eq("username",company.getAccount()));

        //更新
        companyMapper.updateById(company);
    }

    @Override
    @CacheRemove(clazz = CompanyServiceImpl.class, methodName = "getById", param = "#company.id")
    public void update(Company company) {
        companyMapper.updateById(company);
    }


    @Override
    public void save(Company company, String password) {
        //插入公司业务资料
        companyMapper.insert(company);

        //生成门店-总部
        Store store = new Store();
        DataUtil.processEntity(company,store);
        store.setSys(true);
        store.setName("总部");
        store.setRemark("总部在职能上管辖其他门店");
        store.setNo("MD"+ DateUtils.getDate(store.getTime(),DateUtils.YYYYMMDD));
        storeMapper.insert(store);

        //生成默认仓库
        House house = new House();
        DataUtil.processEntity(company,house);
        house.setStoreId(store.getId());
        house.setDef(true);
        house.setSys(true);
        house.setStatus(1);
        house.setName("默认仓库");
        house.setNo("CK"+ DateUtils.getDate(house.getTime(),DateUtils.YYYYMMDD));
        houseMapper.insert(house);

        //生成管理员用户
        User user = new User();
        DataUtil.processEntity(company,user);
        user.setCancelOtherOrder(true);
        user.setName("老板");
        user.setSex(1);
        user.setPhone(company.getPhone());
        String salt = AlgorithmUtil.getCode(8,null, true,true);
        String passwordMd5 = MD5Utils.md5(password,1,salt);
        user.setPassword(passwordMd5);
        user.setSalt(salt);
        user.setUsername(company.getAccount());
        user.setViewOtherCustom(true);
        user.setViewOtherOrder(true);
        user.setViewOtherHouse(true);
        user.setTransferOtherHouse(true);
        user.setStatus(1);
        //价格权限
        user.setPrice("1|2|3|4|5|6");
        user.setStoreId(store.getId());
        userMapper.insert(user);


        //插入角色-管理员
        Role adminRole = new Role();
        DataUtil.processEntity(company,adminRole);
        adminRole.setName("管理员");
        adminRole.setDescription("管理员是系统内置角色，适合公司老板，管理员拥有系统内所有权限。");
        roleMapper.insert(adminRole);

        //用户角色
        UserRole userRole = new UserRole();
        DataUtil.processEntity(company,userRole);
        userRole.setRoleId(adminRole.getId());
        userRole.setUserId(user.getId());
        userRoleMapper.insert(userRole);

        //插入角色权限表
        //获取到所有权限
        List<Permission> permissions = permissionMapper.selectList(new QueryWrapper<Permission>().isNotNull("code"));
        Map<String,Permission> map = new HashMap<>();//key-code  value-id
        List<RolePermission> rolePermissionList = new ArrayList<>();
        for (Permission permission : permissions) {
            map.put(permission.getCode(),permission);
            //生成新的角色权限表
            rolePermissionList.add(genRolePermission(company,adminRole,permission));
        }
        processOtherRole(company,rolePermissionList,map);


        //插入业务设置
        BusinessSet businessSet = new BusinessSet();
        businessSet.setId(UuidUtils.getUUID());
        businessSet.setTime(new Date());
        businessSet.setCompanyId(company.getId());
        businessSet.setDiscount(false);
        businessSet.setNegative(true);
        businessSet.setSerial(false);
        businessSet.setSaleMakeUp(true);
        businessSet.setInMakeUp(true);
        businessSet.setWriteOff(false);
        businessSet.setMoreHouse(true);
        businessSet.setPricePoint(2);
        businessSet.setNumPoint(2);
        businessSet.setOddFlag(4);
        businessSet.setQuickPrint(false);
        businessSet.setInTaxRateFlag(false);
        businessSet.setInTaxRate(new BigDecimal("0"));
        businessSet.setSaleTaxRateFlag(false);
        businessSet.setSaleTaxRate(new BigDecimal("0"));
        businessSet.setHouseInOut(true);
        businessSetMapper.insert(businessSet);

        //插入单号规则
        List<OrderRule> orderRuleList = new ArrayList<>();
        for (OrderType orderType : OrderType.values()) {
            OrderRule orderRule = new OrderRule();
            orderRule.setId(UuidUtils.getUUID());
            orderRule.setCompanyId(company.getId());
            orderRule.setTime(new Date());
            orderRule.setCurrent(0);
            orderRule.setNum(3);
            orderRule.setPrefix(orderType.getAbbr());
            orderRule.setType(orderType.getType());
            orderRuleList.add(orderRule);
        }
        orderRuleMapper.insertBatch(orderRuleList);

        //插入商品属性
        processAttr(company);
    }

    @Override
    public boolean checkAccount(String account) {
        return companyMapper.selectCount(new QueryWrapper<Company>().eq("account",account)) > 0;
    }

    private void processAttr(Company company) {
        List<AttrName> attrNameList = new ArrayList<>();
        String colorNameId = null;
        for (GoodsAttrName goodsAttrName : GoodsAttrName.values()) {
            AttrName attrName = new AttrName();
            DataUtil.processEntity(company,attrName);
            attrName.setName(goodsAttrName.getName());
            attrName.setSort(goodsAttrName.getType());
            attrNameList.add(attrName);
            if (attrName.getName().equals(COLOR.getName())) {
                colorNameId = attrName.getId();
            }
        }
        attrNameMapper.insertBatch(attrNameList);

        if (!Utils.isEmpty(colorNameId)) {
            List<Attr> attrList = new ArrayList<>();
            for (GoodsAttrColor goodsAttrColor : GoodsAttrColor.values()) {
                Attr attr = new Attr();

                DataUtil.processEntity(company,attr);
                attr.setAttrNameId(colorNameId);
                attr.setAttrValue(goodsAttrColor.getName());
                attrList.add(attr);
            }
            attrMapper.insertBatch(attrList);
        }
    }

    private RolePermission genRolePermission(Company company, Role role, Permission permission){
        RolePermission rolePermission = new RolePermission();
        DataUtil.processEntity(company,rolePermission);
        rolePermission.setRoleId(role.getId());
        rolePermission.setPermissionId(permission.getId());
        return rolePermission;
    }

    private void processOtherRole(Company company, List<RolePermission> rolePermissionList, Map<String,Permission> map){
        //插入角色-销售组
        Role xsRole = new Role();
        DataUtil.processEntity(company,xsRole);
        xsRole.setName("销售组");
        xsRole.setDescription("销售组成员能进行销售、销售退货、借出及库存查询操作。");
        roleMapper.insert(xsRole);
        //角色权限-销售订单、销售、销售退货、借出、库存查询
        //销售订单
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("saleOrder:print")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("saleOrder:query")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("saleOrder:verify")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("saleOrder:export")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("saleOrder:insert")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("saleOrder:close")));
        //销售
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("sale:print")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("sale:query")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("sale:export")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("sale:insert")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("sale:close")));
        //销售退货
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("refund:print")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("refund:query")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("refund:export")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("refund:insert")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("refund:close")));
        //库存查询
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("houseQuery:query")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("houseQuery:water")));
        //借出
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("borrowOut:export")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("borrowOut:insert")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("borrowOut:query")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("borrowOut:close")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("borrowOut:print")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("borrowOut:return")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("borrowOut:transferSale")));
        //客户
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("custom:query")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("custom:insert")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("custom:close")));
        //客户分类
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("customType:query")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("customType:insert")));
        rolePermissionList.add(genRolePermission(company,xsRole,map.get("customType:close")));

        //插入角色-财务组
        Role cwRole = new Role();
        DataUtil.processEntity(company,cwRole);
        cwRole.setName("财务组");
        cwRole.setDescription("财务组成员能进行慧管账下的所有操作且可以查看经营状况下的所有报表。");
        roleMapper.insert(cwRole);
        //角色权限-日常收支、收支项目管理、客户应收欠款、供应商应付欠款、资金流水
        //日常收支
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("budget:insert")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("budget:query")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("budget:export")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("budget:close")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("budget:print")));
        //收支项目管理
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("budgetProject:query")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("budgetProject:insert")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("budgetProject:delete")));
        //客户应收欠款
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("arrearsOrder:query")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("arrearsOrder:receipt")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("arrearsOrder:close")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("arrearsOrder:export")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("arrearsOrder:print")));
        //供应商应付欠款
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("payOrder:query")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("payOrder:pay")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("payOrder:close")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("payOrder:export")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("payOrder:print")));
        //资金流水
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("moneyWater:query")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("moneyWater:export")));
        //销售开票
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("saleTicket:query")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("saleTicket:ticket")));
        //账户转账
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("transfer:query")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("transfer:insert")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("transfer:close")));
        //销售报表
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("saleAnalysis:query")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("saleAnalysis:export")));
        //销售退货报表
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("refundAnalysis:query")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("refundAnalysis:export")));
        //进货报表
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("inGoodsAnalysis:query")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("inGoodsAnalysis:export")));
        //进货退货报表
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("inGoodsRefundAnalysis:query")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("inGoodsRefundAnalysis:export")));
        //经营状况报告
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("operateAnalysis:query")));
        //利润报表
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("profitAnalysis:query")));
        //业绩报表
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("performanceAnalysis:query")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("performanceAnalysis:export")));
        //结算账户
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("settAccount:query")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("settAccount:insert")));
        rolePermissionList.add(genRolePermission(company,cwRole,map.get("settAccount:delete")));


        //插入角色-仓库采购组
        Role ckRole = new Role();
        DataUtil.processEntity(company,ckRole);
        ckRole.setName("仓库采购组");
        ckRole.setDescription("仓管采购组成员能进行进货、进货退货、借入借出、盘点、组装拆卸、库存调拨及查询操作。同时能查看与上述业务相关的报表。");
        roleMapper.insert(ckRole);
        //角色权限-进货订单、进货、进货退货、库存盘点、组装拆卸、调拨历史单、入库、出库、借出单、借入单、库存查询、进货报表
        //进货订单
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoodsOrder:query")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoodsOrder:insert")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoodsOrder:close")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoodsOrder:export")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoodsOrder:print")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoodsOrder:verify")));
        //进货订单
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoods:query")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoods:insert")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoods:close")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoods:export")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoods:print")));
        //进货退货
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoodsRefund:query")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoodsRefund:insert")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoodsRefund:close")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoodsRefund:export")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("inGoodsRefund:print")));
        //库存盘点
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("checkHouse:query")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("checkHouse:insert")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("checkHouse:close")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("checkHouse:export")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("checkHouse:print")));
        //组装拆卸
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("joinSplit:query")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("joinSplit:insert")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("joinSplit:close")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("joinSplit:export")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("joinSplit:print")));
        //调拨历史单
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("goodsTransfer:query")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("goodsTransfer:insert")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("goodsTransfer:close")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("goodsTransfer:export")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("goodsTransfer:print")));
        //入库
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("houseIn:query")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("houseIn:houseIn")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("houseIn:close")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("houseIn:export")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("houseIn:print")));
        //出库
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("houseOut:query")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("houseOut:houseOut")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("houseOut:close")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("houseOut:export")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("houseOut:print")));
        //借入单
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("borrowIn:query")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("borrowIn:insert")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("borrowIn:close")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("borrowIn:export")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("borrowIn:print")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("borrowIn:return")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("borrowIn:transferIn")));
        //库存查询
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("houseQuery:query")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("houseQuery:export")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("houseQuery:water")));
        //供应商
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("provider:query")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("provider:insert")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("provider:close")));
        //供应商分类
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("providerType:query")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("providerType:insert")));
        rolePermissionList.add(genRolePermission(company,ckRole,map.get("providerType:close")));
        rolePermissionMapper.insertBatch(rolePermissionList);
    }
}
